home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!gatech!cwjcc!hal!ncoast!allbery
- From: chad@anasaz.UUCP
- Newsgroups: comp.sources.misc
- Subject: v04i091: simple formatting filter for text editors
- Message-ID: <8809241116.AA21251@noao.edu>
- Date: 25 Sep 88 01:29:37 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: chad@anasaz.UUCP ()
- Lines: 436
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 4, Issue 91
- Submitted-by: "A. Nonymous" <chad@anasaz.UUCP>
- Archive-name: fill
-
- This is another simple filter to make it easier to enter and revise
- text from within vi or some other editor. It provides centering,
- filling and justification on selectable margins.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: fill.c fill.1 Makefile test_file
- # Wrapped by chad@dcfinc on Sat Sep 24 01:29:59 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'fill.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fill.c'\"
- else
- echo shar: Extracting \"'fill.c'\" \(8314 characters\)
- sed "s/^X//" >'fill.c' <<'END_OF_FILE'
- X/* fill.c - Simple text formatter - 1.7 */
- X
- X/*
- X** fill is a simple text formatter meant to be used from within
- X** your editor to provide the same functionality as the ^B command
- X** in WordStar. This presumes your editor can pipe an object through
- X** a filter. In vi, you would do something like "!}fill" to word wrap
- X** a paragraph. Of course, you may, in the spirit of Unix, find other
- X** uses for it. For example, fill has the side-effect of de-tabifying
- X** lines passed to it.
- X** Usage: fill [-c | -j] [-l n] [-o n]
- X** -c center the lines
- X** -j justify the right margin
- X** -r n set right margin to "n", defaults to 72
- X** -l n set left margin to "n", defaults to 1
- X*/
- X
- X/*
- X** Author:
- X** Chad R. Larson This program is placed in the
- X** DCF, Inc. Public Domain. You may do with
- X** 14623 North 49th Place it as you please.
- X** Scottsdale, AZ 85254
- X*/
- X
- X/*
- X** Programming note: functions from the string library were used
- X** wherever logical, under the assumption that they are more optimized
- X** (or assemblerized) than whatever I built would be. On my C library
- X** this is true, your milage may vary. Buffer pointers were generally
- X** avoided for readability (this doesn't have to blaze, after all).
- X*/
- X
- X/* maximum length of a line (for centering only) */
- X#define LINE_MAX 512
- X
- X/* maximum length of a word */
- X#define WORD_MAX 128
- X
- X/* the default right margin */
- X#define DEF_MARGIN 72
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <memory.h>
- X
- X/* forward references */
- Xvoid j_line(); /* justify a line */
- Xvoid exit();
- Xchar *malloc();
- X
- X
- X/* main program */
- Xvoid main(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int c; /* a generic character */
- X int center = 0; /* center text flag */
- X int justify = 0; /* justify right margin flag */
- X int w_length; /* length of current word */
- X int l_length = 0; /* length of current line */
- X int l_margin = 1; /* left margin */
- X int r_margin = DEF_MARGIN; /* right margin */
- X int wrap_point; /* max chars allowed on a line */
- X char *margin; /* points to left margin string */
- X char *out_line; /* points to the output line */
- X char word[WORD_MAX]; /* the current word */
- X char *bp; /* a buffer pointer for centering */
- X extern char *optarg; /* option argument pointer
- X
- X /* parse the command line */
- X while ((c = getopt(argc, argv, "cjr:l:")) != EOF)
- X switch (c) {
- X case 'c':
- X center++;
- X break;
- X case 'j':
- X justify++;
- X break;
- X case 'r':
- X r_margin = atoi(optarg);
- X break;
- X case 'l':
- X l_margin = atoi(optarg);
- X break;
- X case '?':
- X (void)fprintf(stderr,
- X "Usage: %s [-c | -j] [-l n] [-o n]\n", argv[0]);
- X exit(-1);
- X }
- X
- X /* validate command line inputs */
- X if ( justify && center ) {
- X (void)fputs("Center and Justify are mutually exclusive.\n", stderr);
- X exit(1);
- X }
- X if (l_margin >= r_margin || l_margin < 1) {
- X (void)fputs("Illogical margin setting.\n", stderr);
- X exit(2);
- X }
- X
- X /* Center the text if requested. Will exit without filling. */
- X if (center) {
- X if ( (out_line = malloc(LINE_MAX)) == NULL ) {
- X (void)fputs("Unable to allocate centering buffer.\n", stderr);
- X exit(3);
- X }
- X while ( fgets(out_line, LINE_MAX, stdin) != NULL ) {
- X bp = out_line;
- X while (*bp == ' ' || *bp == '\t') /* strip leading spaces */
- X bp++;
- X l_length = strlen(bp);
- X l_length--; /* back over new-line */
- X while (bp[l_length - 1] == ' ' || bp[l_length - 1] == '\t')
- X l_length--; /* strip trailing space */
- X bp[l_length] = '\0';
- X center = (r_margin - l_length) / 2;
- X while (center--)
- X (void)putc(' ', stdout);
- X (void)puts(bp);
- X }
- X exit(0);
- X }
- X
- X /* create the left margin string */
- X if ( (margin = malloc( (unsigned)l_margin) ) == NULL ) {
- X (void)fputs("Unable to allocate space for margin.\n", stderr);
- X exit(4);
- X }
- X (void)memset(margin, ' ', l_margin - 1);
- X margin[l_margin - 1] = '\0';
- X
- X /* create the output line buffer */
- X wrap_point = r_margin - l_margin + 1;
- X if ((out_line = malloc( (unsigned)wrap_point + 3) ) == NULL) {
- X (void)fputs("Unable to allocate space for line buffer.\n", stderr);
- X exit(5);
- X }
- X
- X /* move words from the input to the output */
- X while ( (w_length = get_word(word) ) != 0 ) {
- X if ( (l_length + w_length) > wrap_point ) { /* line wrap? */
- X while (out_line[l_length - 1] == ' ') /* trailing space strip */
- X l_length--;
- X out_line[l_length] = '\0';
- X if (justify) /* justify the line? */
- X j_line(out_line, wrap_point);
- X (void)fputs(margin, stdout); /* set any offset */
- X (void)puts(out_line); /* put the line to stdout */
- X *out_line = '\0'; /* reset the output line */
- X l_length = 0;
- X }
- X (void)strcat(out_line, word);
- X (void)strcat(out_line, " ");
- X l_length = l_length + w_length + 1;
- X if ( (c = word[w_length - 1]) == '.' || c == '?' || c == '!' ) {
- X (void)strcat(out_line, " "); /* end-of-sentence handling */
- X l_length++;
- X }
- X }
- X
- X /* clean up and exit */
- X if (l_length) { /* residual to flush */
- X while (out_line[l_length - 1] == ' ')
- X l_length--;
- X out_line[l_length] = '\0';
- X (void)fputs(margin, stdout);
- X (void)puts(out_line);
- X }
- X exit(0);
- X}
- X
- X/*
- X** get_word - a routine to return the next word from the standard input.
- X** Copies the next word from the input stream to the location pointed to
- X** by its argument. The word will be null terminated. A word is any
- X** string of characters delimited by whitespace. Returns the length
- X** of the word.
- X*/
- X
- Xint get_word(Word)
- Xchar *Word;
- X{
- X register int c; /* generic character */
- X register int i; /* a counter */
- X
- X /* first strip any leading whitespace */
- X while ((c = getchar()) == ' ' || c == '\n' || c == '\t' || c == '\f') ;
- X if (c == EOF) {
- X *Word = '\0';
- X return 0;
- X } else
- X (void)ungetc(c, stdin);
- X
- X /* copy the word */
- X i = 0;
- X while ((c = getchar()) != ' ' && c != '\n'
- X && c != '\t' && c != '\f' && c != EOF) {
- X *Word++ = c;
- X if (++i >= WORD_MAX) {
- X (void)fputs("Encountered word too large.\n", stderr);
- X exit(6);
- X }
- X }
- X *Word = '\0';
- X return i;
- X}
- X
- X/*
- X** Routine to justify a line.
- X*/
- Xvoid j_line(buffer, margin)
- Xchar *buffer;
- Xint margin;
- X{
- X static unsigned direction = 0; /* which end to we fill from? */
- X static char *work = NULL; /* working storage */
- X int insert; /* count of places to insert */
- X int spaces; /* count of spaces to insert */
- X int multi; /* spaces to insert each chance */
- X int extra; /* count of extra spaces needed */
- X int count; /* loop counter */
- X int loop; /* loop counter */
- X char *Ibp; /* Input buffer pointer */
- X char *Obp; /* Output buffer pointer */
- X
- X /*
- X ** Allocate a working storage large enough to hold the line. We
- X ** only do this once (and only if we are justifing).
- X */
- X if (work == NULL)
- X if ((work = malloc( (unsigned)margin + 1 )) == NULL) {
- X (void)fputs("Unable to allocate work buffer.\n", stderr);
- X exit(7);
- X }
- X
- X /* how many spaces do we have to insert? */
- X loop = strlen(buffer);
- X spaces = margin - loop;
- X if (spaces == 0)
- X return;
- X
- X /* find how many opportunities there are for space stuffing */
- X Ibp = buffer;
- X insert = 0;
- X while (loop--) {
- X if ( (*Ibp++ == ' ') && (*Ibp != ' ') )
- X insert++;
- X }
- X if (insert == 0)
- X return;
- X
- X /* how many spaces do we have to stuff per chance? */
- X extra = spaces % insert; /* extra spaces needed */
- X multi = spaces / insert; /* spaces per slot to insert */
- X
- X /* copy the buffer contents, inserting spaces */
- X direction = ~direction; /* flip end to fill from */
- X (void)strcpy(work, buffer); /* make a working copy */
- X if (direction) {
- X Ibp = work;
- X Obp = buffer;
- X loop = strlen(buffer) + 1;
- X while (loop--) {
- X *Obp++ = *Ibp++; /* move a character */
- X if ((*(Ibp - 1) == ' ') && (*(Ibp - 2) != ' ')) {
- X if (extra) {
- X extra--;
- X *Obp++ = ' ';
- X }
- X for (count = multi; count; count--)
- X *Obp++ = ' ';
- X }
- X }
- X } else {
- X loop = strlen(buffer);
- X Ibp = work + loop;
- X Obp = buffer + loop + spaces;
- X *(Obp + 1) = '\0';
- X while (loop--) {
- X *Obp-- = *Ibp--;
- X if ((*(Ibp + 1) == ' ') && (*(Ibp + 2) != ' ')) {
- X if (extra) {
- X extra--;
- X *Obp-- = ' ';
- X }
- X for (count = multi; count; count--)
- X *Obp-- = ' ';
- X }
- X }
- X }
- X}
- END_OF_FILE
- if test 8314 -ne `wc -c <'fill.c'`; then
- echo shar: \"'fill.c'\" unpacked with wrong size!
- fi
- # end of 'fill.c'
- fi
- if test -f 'fill.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fill.1'\"
- else
- echo shar: Extracting \"'fill.1'\" \(1177 characters\)
- sed "s/^X//" >'fill.1' <<'END_OF_FILE'
- X.TH FILL 1 local
- X.SH NAME
- Xfill - a simple text formatter
- X.SH SYNOPSIS
- Xfill [-c | -j] [-r n] [-l n]
- X.SH DESCRIPTION
- X.I Fill
- Xis a simple text formatter meant to be used from within
- Xyour editor to provide the same functionality as the ^B command
- Xin WordStar. This presumes your editor can pipe an object through
- Xa filter. In vi, you would do something like "!}fill" to word wrap
- Xa paragraph. Of course, you may, in the spirit of Unix, find other
- Xuses for it. For example,
- X.I fill
- Xhas the side-effect of de-tabifying
- Xlines passed to it.
- X.PP
- XThe following options pertain:
- X.nf
- X -c center the lines
- X -j justify the right margin
- X -r n set right margin to "n", defaults to 72
- X -l n set left margin to "n", defaults to 1
- X.fi
- X.SH CAVEATS
- XThis ability is built in to emacs (but then, what isn't). It is
- Xrumored a similar program exists in the Berkely world.
- X.SH FEATURES
- X.I Fill
- Xhas no pracical limit on line lengths (except when centering).
- X.SH BUGS
- XThe justification algorithm is a little crude.
- X.br
- X.I Fill
- Xmakes no attempt to preserve existing indentations or blank
- Xlines (this could be construed as a feature).
- X.SH AUTHOR
- XChad R. Larson
- X.SH "SEE ALSO"
- Xpr(1), nroff(1), troff(1)
- END_OF_FILE
- if test 1177 -ne `wc -c <'fill.1'`; then
- echo shar: \"'fill.1'\" unpacked with wrong size!
- fi
- # end of 'fill.1'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(243 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# Makefile for fill, a simple text formatter
- X#
- X# Last changed 9/23/88
- X#
- X
- XBINDIR = /usr/local/bin
- X
- Xfill: fill.c
- X $(CC) $(CFLAGS) -o fill fill.c
- X
- Xinstall: fill
- X strip fill
- X -ln fill $(BINDIR)
- X touch install
- X
- XLint: fill.c
- X lint -p fill.c >Lint
- END_OF_FILE
- if test 243 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'test_file' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'test_file'\"
- else
- echo shar: Extracting \"'test_file'\" \(852 characters\)
- sed "s/^X//" >'test_file' <<'END_OF_FILE'
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- XThis is just a silly file of words to see if fill wraps them properly.
- END_OF_FILE
- if test 852 -ne `wc -c <'test_file'`; then
- echo shar: \"'test_file'\" unpacked with wrong size!
- fi
- # end of 'test_file'
- fi
- echo shar: End of shell archive.
- exit 0
- ---------------
- "I read the news today, oh boy!" --John Lennon
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- | DCF, Inc. | UUCP: ...ncar!noao!nud!anasaz!dcfinc!chad |
- | 14623 North 49th Place | Ma Bell: (602) 953-1392 |
- | Scottsdale, AZ 85254 | Loran: N-33deg37min20sec W-111deg58min26sec |
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- | Disclaimer: These ARE the opinions of my employer! |
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-